package learn.arc.spring;

import com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl;
import com.sun.org.apache.xerces.internal.impl.XMLVersionDetector;
import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl;
import com.sun.org.apache.xerces.internal.parsers.DOMParser;
import com.sun.org.apache.xerces.internal.parsers.XML11Configuration;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import learn.arc.mybatis.Mybatis;
import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.*;
import org.apache.catalina.startup.*;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.initializer.DubboApplicationContextInitializer;
import org.apache.dubbo.spring.boot.context.DubboApplicationContextInitializer;
import org.apache.ibatis.io.Resources;
import org.apache.tomcat.util.digester.Digester;
import org.aspectj.lang.annotation.*;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.*;
import org.springframework.beans.factory.support.*;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.DefaultDocumentLoader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.OnBeanCondition;
import org.springframework.boot.autoconfigure.condition.OnPropertyCondition;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.boot.context.event.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle;
import org.springframework.context.*;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.annotation.*;
import org.springframework.context.event.*;
import org.springframework.context.support.*;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.env.*;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.transaction.jta.UserTransactionAdapter;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringValueResolver;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.web.SpringServletContainerInitializer;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.*;
import org.springframework.web.context.support.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.xml.sax.InputSource;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebListener;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAResource;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.net.URI;
import java.net.URL;
import java.util.EventObject;
import java.util.function.Supplier;

/**
 * 配置
 *  容器配置。web.xml
 *  属性配置。环境配置，properties、yml、xml等
 *  bean配置。xml、java类、factories(springboot)
 *
 * 解耦方式：SPI、观察者模式(监听器)、
 * beanFactory预实例化单例bean前，冻结beanDefinition集合，不再修改
 *
 * 核心
 *  bd、bean、事件/监听器
 *
 * bd集合过程
 *  bf扫描注册
 *  BeanDefinitionRegistryPostProcessor；注册新bd，如处理@Configuration类
 *  BeanFactoryPostProcessor；修改bd
 *  冻结bd集合
 *  MergedBeanDefinitionPostProcessor；bd待注入属性扫描
 *  InstantiationAwareBeanPostProcessor.postProcessProperties；调整注入属性kv
 *
 */
public class Spring {

    /**
     *
     */
    public static void tomcat(){
        Catalina catalina;//
        Tomcat tomcat;// 内嵌、测试
        Server server;// tomcat服务器
        Service service;// 一组connector、engine
        Connector connector;// 端口连接器，同协议也可配置多个
        Engine engine;// 全部servlet的集合引擎
        Host host;// 虚拟主机
        Context context;// 应用上下文
        Wrapper wrapper;// servlet包装

        // Server及以下实现；生命周期接口
        org.apache.catalina.Lifecycle lifecycle;
        // 继承Lifecycle，Engine及以下实现；执行请求，返回结果
        Container container;

    }

    /**
     * 启动过程
     *  观察者模式；启动spring
     *  适配器，转换容器context、spring context
     *
     *  在Catalina的load方法里，就已经调用了StandardServer里的init方法，一层一层初始化。
     *      StandardServer--》
     *      globalNamingResources，StandardService--》
     *      StandardEngine，executors，MapperListener，Connector--》
     *      CoyoteAdapter，protocolHandler
     *  至此就将tomcat的catalina中的组件、容器初始化完成。 接下来就是调用start方法一层一层开启，StandardServer的startInternal方法，按层次start：
     *      StandardServer--》
     *      globalNamingResources，StandardService--》
     *      StandardEngine，executors，MapperListener，Connector--》
     *      StandardHost，StandardContext，protocolHandler。
     *  顺序基本同init过程。StandardEngine在start时，会init子容器，并调用子容器的start方法。子容器依次这样init、start，就开启了StandardHost和StandardContext
     *
     */
    public static void start(){
        Bootstrap.main(null);// 启动类入口
        {
            // 1，初始化类加载器和创建Catalina实例，然后再启动Catalina线程
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.init();
            Catalina catalina=null;
            {
                // 创建common、server、shared类加载器，对应不同加载路径
                // catalina.properties；配置类加载器的加载路径，无加载路径则返回父加载器
                // common为server、shared父加载器
                bootstrap.initClassLoaders();
                CatalinaProperties catalinaProperties;// 读入catalina.properties，设置到os
                // server的类加载器加载Catalina类，反射实例化
                // 设置catalina共享的类加载器为shared
            }

            // 2，按命令，反射调用catalina方法
            // 默认start？
            {
                // 1，调用catalina.setWait
                bootstrap.setAwait(true);
                catalina.setAwait(true);
                // 2，调用catalina.load
                bootstrap.load();
                catalina.load(null);
                {
                    // 校验命令行参数；
                    catalina.arguments(null);
                    // 启动server
                    catalina.load();
                    {
                        // 1，校验os java.io.tmpdir属性
                        catalina.initDirs();
                        // 2，处理命名相关os变量
                        catalina.initNaming();
                        // 3，创建Digester，解析server.xml，构建server
                        // server.xml搜索路径：conf，classLoader conf、server-embed
                        Digester digester = catalina.createStartDigester();
                        digester.parse((InputSource)null);
                        // 4，设置server属性；catalina、catalinaHome、catalinaBase
                        // 5，调用server.init；初始化StandardService，StandardEngine、Connector等
                        Server server = null;
                        ((StandardServer)server).init();
                        ((StandardServer)server).initInternal();

                    }
                }
                // 3，层级start
                bootstrap.start();
                {
                    catalina.start();
                    new StandardServer().startInternal();
                    new StandardService().startInternal();
                    new StandardEngine().startInternal();
                    new Connector().startInternal();
                    new StandardHost().startInternal();
                    new StandardContext().startInternal();// 读取web.xml
                    {
                        ContextConfig contextConfig=null;
                        contextConfig.lifecycleEvent(null);
                        String trigConfLoad = org.apache.catalina.Lifecycle.CONFIGURE_START_EVENT;
                        contextConfig.configureStart();
                        contextConfig.webConfig();// 读取web.xml
                    }
                    new StandardContext().loadOnStartup(null);// startInternal调用
                    {
                        StandardWrapper standardWrapper = new StandardWrapper();
                        standardWrapper.load();
                        standardWrapper.loadServlet();// 反射实例化servlet，注入rootContext？
                        standardWrapper.initServlet(null);// 调用init方法
                    }
                }
            }

        }

        ContextLoaderListener loaderListener;// 加载spring
        DispatcherServlet dispatcherServlet=null;// 加载servlet，加载mvc
        XmlWebApplicationContext servletContext;

    }
    /**
     * 一个应用，一个StandardContext，即一个ServletContext
     *
     */
    public static void context(){
        // tomcat
        StandardContext standardContext;// ServletContextEvent事件监听器，触发spring、springMVC加载
        org.apache.catalina.core.ApplicationContext applicationContext2;// 适配器模式，StandardContext转ServletContext；facede属性

        // javax
        ServletConfig servletConfig;// servletName、initParam、servletContext
        ServletContext servletContext;

        // spring
        ApplicationContext applicationContext;
        WebApplicationContext webApplicationContext;// 实现类，组合ServletContext


        // web容器的全局上下文环境，为后面的spring IoC容器提供宿主环境。web.xml
        // WebListener、Filter、Servlet
        ServletContext serverContext;
        // spring上下文；存储到serverContext。bean配置
        // @Component等bean
        WebApplicationContext rootContext;
        // spring mvc上下文；rootContext为父级，存储到serverContext
        // bean查找时，先servletContext1，后rootContext
        // mvc相关bean，如9组件？
        WebApplicationContext servletContext1;
        // 获取上下文
        RequestContextUtils.findWebApplicationContext(null);

    }

    /**
     * 观察者模式启动
     * ContextLoader三属性：currentContextPerThread、currentContext、context(rootContext)
     */
    public static void tomcatSpringStart(){
        SpringServletContainerInitializer containerInitializer;
        WebApplicationInitializer initializer2;// spring tomcat容器初始化回调。spring context

        ServletContextEvent event = null;// 监听的事件，tomcat发布
        // 加载spring。@WebListener、ServletContext#addListener载入(web.xml)
        ContextLoaderListener loaderListener=null;
        loaderListener.contextInitialized((ServletContextEvent)event);
        {
            ServletContext serverContext = event.getServletContext();
            loaderListener.initWebApplicationContext((ServletContext)serverContext);
            {
                // 从serverContext获取getInitParameter contextClass，反射实例化
                // 上下文默认XmlWebApplicationContext，ContextLoader.properties
                // 创建的context存于ContextLoader对象，确保处理serverContext关闭事件时可见
                WebApplicationContext rootContext = loaderListener.createWebApplicationContext((ServletContext)serverContext);
                // 设置父context
                // 配置、刷新上下文
                loaderListener.configureAndRefreshWebApplicationContext(rootContext, serverContext);
                {
                    // 获取、设置上下文id
                    // rootContext关联serverContext
                    // 从serverContext中获取contextConfigLocation

                    // 加载环境变量。命令行、os、jvm、配置文件等
                    ConfigurableEnvironment env = rootContext.getEnvironment();
                    ((ConfigurableWebEnvironment) env).initPropertySources(serverContext, (ServletConfig)null);
                    {
                        MutablePropertySources propertySources = env.getPropertySources();// new MutablePropertySources()
                        // 载入serverContext、ServletConfig作为PropertySource。获取web.xml contextParam
                        WebApplicationContextUtils.initServletPropertySources(null, serverContext, (ServletConfig)null);
                        ServletContextPropertySource servletContextPropertySource;// StandardContext，web.xml中contextParam、服务器默认初始化参数
                        ServletConfigPropertySource servletConfigPropertySource;
                    }
                    // 上下文自定义处理；
                    // servletContext globalInitializerClasses、contextInitializerClasses配置
                    loaderListener.customizeContext(serverContext, rootContext);
                    ApplicationContextInitializer applicationContextInitializer;
                    // 刷新上下文
                    ((ConfigurableWebApplicationContext)rootContext).refresh();
                }
                // rootContext存入serverContext
            }

        }

        // 加载mvc
        DispatcherServlet dispatcherServlet=null;
        // 容器启动，servlet.init；根据servletContext创建webContext；
        dispatcherServlet.init();
        dispatcherServlet.createWebApplicationContext(null);
        dispatcherServlet.configureAndRefreshWebApplicationContext(null);
        AbstractApplicationContext.refresh();
        // 构建非懒加载单例bean
        AbstractApplicationContext.finishBeanFactoryInitialization();
        DefaultListableBeanFactory.preInstantiateSingletons();
        // mvc。9组件
        dispatcherServlet.initStrategies(null);
    }

    /**
     *  WebApplicationInitializer。容器初始化回调，容器参数初始化rootContext；refresh
     *
     * 上下文刷新，加载spring配置信息；不变+变动
     *  不变：servletContext、environment引用
     *  变动：属性配置、bean配置。属性配置重载，bean配置中单例的重载
     * 门面模式
     * https://blog.csdn.net/f641385712/article/details/88059145
     *
     * 重点：
     *  prepareBeanFactory；载入beanDefinition
     *  finishBeanFactoryInitialization；单例bean实例化
     *  读取构建BeanDefinition；按BeanDefinition初始化bean，修改BeanFactory相关信息
     *  initialization，初始化；instantiation，实例化
     */
    public static void refresh() throws Exception {
        AbstractApplicationContext rootContext = null;// AbstractRefreshableWebApplicationContext
        rootContext.refresh();
        {
            /* step1，设置标记；初始化PropertySources、环境*/
            rootContext.prepareRefresh();
            {
                // 载入serverContext、ServletConfig作为PropertySource。获取web.xml contextParam
                rootContext.initPropertySources();

                // 校验必需的属性
                rootContext.getEnvironment().validateRequiredProperties();
                StandardEnvironment standardEnvironment;
            }
            /* step2，刷新beanFactory；并返回*/
            ConfigurableListableBeanFactory beanFactory = rootContext.obtainFreshBeanFactory();
            {
                /* 1，销毁单例bean，关闭beanFactory
                 *      清空bean相关集合；
                 * 2，创建beanFactory
                 *      rootContext parent为null，即无parent ApplicationContext
                 * 3，beanDefinition覆盖、循环依赖设置
                 * 4，加载beanDefinition。api添加、路径扫描、配置文件指定位置
                 *      创建beanDefinitionReader
                 *      初始化reader；
                 *      执行加载beanDefinition，构建bean相关集合
                 *
                 */
                ((AbstractRefreshableWebApplicationContext)rootContext).refreshBeanFactory();
                {
                    ((AnnotationConfigWebApplicationContext)rootContext).loadBeanDefinitions();
                    AnnotatedBeanDefinitionReader classReader;// 扫描代码注册的class
                    AnnotationConfigRegistry annotationConfigRegistry;// 直接注册配置类、bean类
                    ClassPathBeanDefinitionScanner dirReader;// 路径扫描注解bean，通过Resource加载类信息
                    BeanDefinitionParser beanDefinitionParser;// xml bean扫描

                }
                // 返回重新创建的beanFactory
                rootContext.getBeanFactory();
            }
            /* step3，载入固定BeanPostProcessor、注册固定bean等*/
            rootContext.prepareBeanFactory(beanFactory);
            /* step4，上下文beanFactory初始化后回调*/
            rootContext.postProcessBeanFactory(beanFactory);
            /* step5，执行BeanFactoryPostProcessor*/
            rootContext.invokeBeanFactoryPostProcessors(beanFactory);
            {
                // 1，BeanFactoryPostProcessor加载、代理执行；框架加载、bean加载(预实例化对应bean)
                // 先执行BeanDefinitionRegistryPostProcessor，已有、bean(PriorityOrdered、Ordered、普通)
                // 执行 BeanFactoryPostProcessor，已有、bean
                PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, null);
                // BeanFactoryPostProcessor方式处理Environment占位符

                // 2，载入LoadTimeWeaver



            }
            /* step5，加载BeanPostProcessor*/
            rootContext.registerBeanPostProcessors(beanFactory);
            {
                // 实例化bean，注入到beanFactory
                PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, rootContext);
            }
            /* step6，注册MessageSource bean*/
            rootContext.initMessageSource();
            /* step7，注册ApplicationEventMulticaster bean*/
            rootContext.initApplicationEventMulticaster();
            /* step8，单例bean实例化前，调用特殊bean的初始化方法*/
            rootContext.onRefresh();
            /* step9，ApplicationEventMulticaster绑定ApplicationListener，发布事件，初始化ApplicationListener bean*/
            // ApplicationEventPublisher，组合ApplicationEventMulticaster
            rootContext.registerListeners();
            /* step10，实例化饿汉式单例bean，并初始化*/
            rootContext.finishBeanFactoryInitialization(beanFactory);
            {
                // 实例化类型转换bean；
                ConversionService conversionService;
                // 无占位符解析器时，注册environment的解析器
                StringValueResolver valueResolver;
                // 实例化LoadTimeWeaverAware；监听织入器类的加载
                LoadTimeWeaverAware loadTimeWeaverAware;
                LoadTimeWeaver loadTimeWeaver;
                ClassFileTransformer classFileTransformer;
                // 停用临时类加载器；设为null

                // 缓存BeanDefinition，不再变动
                // configurationFrozen = true，frozenBeanDefinitionNames=StringUtils.toStringArray(this.beanDefinitionNames)
                beanFactory.freezeConfiguration();
                // 遍历，预实例化非懒汉的单例bean
                beanFactory.preInstantiateSingletons();
                {
                    // 实例化
                    beanFactory.getBean("");
                    // 调用post-initialization callback
                    SmartInitializingSingleton smartInitializingSingleton;

                }

            }
            /* step11，清除缓存*/
            rootContext.finishRefresh();
            /* step12，清除缓存*/
            rootContext.resetCommonCaches();
        }
    }

    /**
     * 加载servlet，加载mvc
     *  加载servlet时机。web.xml
     *  加载mvc方式
     *
     */
    public static void mvc(){
        // spring3.1后，容器启动回调，初始化dispatcher。spi、容器发现加载
        AbstractDispatcherServletInitializer webApplicationInitializer=null;
        // 引入dispatcher bean；springboot
        DispatcherServletAutoConfiguration config;

        // web.xml、WebApplicationInitializer加载；
        webApplicationInitializer.onStartup((ServletContext)null);// 创建rootContext，注册dispatcher
        webApplicationInitializer.registerDispatcherServlet((ServletContext)null);

        DispatcherServlet dispatcher=new DispatcherServlet((WebApplicationContext)null);
        dispatcher.init((ServletConfig) null);// 初始化回调
        {
            ((HttpServletBean)dispatcher).init();// Servlet#init，设置init-param参数，调用initServletBean
            ((FrameworkServlet)dispatcher).initServletBean();// 自定义初始化
            {
                // 初始化servletContext；无时：serverContext获取，传入rootContext新建并刷新
                ((FrameworkServlet)dispatcher).initWebApplicationContext();
                // servlet刷新，调用dispatcher.initStrategies
                dispatcher.onRefresh(null);
            }



            // 初始化mvc 9组件
            ApplicationContext context=null;
            dispatcher.initStrategies(context);
            {
                // 1，初始化分段文件解析器
                dispatcher.initMultipartResolver(context);
                // 2，初始化本地化解析器
                dispatcher.initLocaleResolver(context);
                // 3，初始化主题解析器
                dispatcher.initThemeResolver(context);
                // 4，初始化HandlerMapping
                dispatcher.initHandlerMappings(context);
                // 5，初始化HandlerAdapter
                dispatcher.initHandlerAdapters(context);dispatcher.getServletContext()
                // 6，初始化异常处理器
                dispatcher.initHandlerExceptionResolvers(context);
                // 7，初始化RequestToViewNameTranslator，请求转视图
                dispatcher.initRequestToViewNameTranslator(context);
                // 8，初始化视图解析器
                dispatcher.initViewResolvers(context);
                // 9，初始化FlashMap管理器，用于重定向时暂存请求数据
                dispatcher.initFlashMapManager(context);
            }

            // 序列化？消息转换器？
        }

        /*
         * 上下文层级
         *  1，serverContext持有rootContext、servletContext
         *  2，rootContext持有serverContext、servlet。无配置时为null
         *  3，servletContext持有rootContext。无servlet config配置时为空对象
         *  4，bean查找时，从下往上，可覆盖。
         */
        ServletContext serverContext;
        WebApplicationContext rootContext;// 公用
        WebApplicationContext servletContext;// servlet自定义上下文
        {
            WebApplicationContext webApplicationContext = RequestContextUtils.findWebApplicationContext((HttpServletRequest) null);

            ContextLoaderListener loaderListener = null;
            loaderListener.contextInitialized(null);// 容器上下文初始化回调；serverContext关联rootContext，rootContext刷新
            dispatcher.init(null);// 容器启动回调；servletContext关联rootContext
            org.apache.catalina.Lifecycle lifecycle;// 生命周期：init；start；stop；destroy

        }

        // 接口定义结构；模板方法扩展
        Servlet servlet;// java定义
        GenericServlet genericServlet;// 通用servlet模板，协议无关。抽象类
        HttpServlet httpServlet;// http servlet；抽象，继承以处理请求
        HttpServletBean httpServletBean;// init-param通过bean属性解析，从servletConfig获取
        FrameworkServlet frameworkServlet;// spring基础servlet；提供servletContext管理，req请求事件发布
        DispatcherServlet dispatcherServlet;

    }


    /**
     *
     */
    public static void other(){
        /* step1，配置信息 https://www.cnblogs.com/zhchoutai/p/6880165.html*/
        // xml，声明PropertyPlaceholderConfigurer bean、context:property-placeholder导入
        Environment environment;// 包含os、jvm参数
        MutablePropertySources propertySources;

        // 实现BeanFactoryPostProcessor；预加载bean，导入配置
        PropertyPlaceholderConfigurer propertyPlaceholderConfigurer;
        // 占位符解析
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer;



    }

    /**
     *
     */
    public static void event(){
        EventObject eventObject;

        /* step1，tomcat容器事件、监听器*/
        java.util.EventListener eventListener;
        ServletContextListener servletContextListener;
        // 上下文事件；StandardContext#listenerStart/listenerStop
        // 初始化完成、销毁后回调
        ServletContextEvent servletContextEvent;

        /* step2，spring、springboot事件、监听器基类*/
        ApplicationEvent event;
        ApplicationEventPublisher eventPublisher;// 组合ApplicationEventMulticaster
        ApplicationListener listener;
        EventListener listenerAnno;

        // spring上下文事件；
        // https://docs.spring.io/spring-framework/docs/5.3.10/reference/html/core.html#context-functionality-events
        ApplicationContextEvent applicationContextEvent;
        {
            // 容器初始化、刷新
            ContextRefreshedEvent refreshedEvent;
            // bean启动/重启
            ContextStartedEvent startedEvent;
            Lifecycle lifecycle;// start方法
            // bean销毁
            ContextStoppedEvent stoppedEvent;
            // 容器销毁
            ContextClosedEvent closedEvent;
        }

        // springboot事件
        // https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.spring-application.application-events-and-listeners
        SpringApplicationEvent springApplicationEvent;
        {
            ApplicationStartingEvent startingEvent;// 调用run()方法后。
            ApplicationEnvironmentPreparedEvent environmentPreparedEvent;// Environment加载完毕。
            ApplicationContextInitializedEvent contextInitializedEvent;// beanDefinition加载前。
            ApplicationPreparedEvent preparedEvent;// bean装配前，beanDefinition加载后。
            ApplicationStartedEvent startedEvent;// bean装配完毕，CommandLineRunner前。
            ApplicationReadyEvent readyEvent;// CommandLineRunner回调完毕。
            ApplicationFailedEvent failedEvent;// 启动失败
        }



    }

    /**
     *
     */
    public static void extendClass(){
        /* step1，编程式配置web.xml；https://blog.csdn.net/z69183787/article/details/104557820*/
        // 实际会适配到ServletContainerInitializer，容器初始化后回调，spi、容器发现加载
        WebApplicationInitializer initializer;
        {
            /* jdk 容器初始化回调*/
            ServletContainerInitializer servletContainerInitializer;
            // 适配器模式，spi；WebApplicationInitializer，ServletContainerInitializer
            SpringServletContainerInitializer containerInitializer;
            {
                // 监听器读取；spi机制加载
                // ContextConfig实现LifecycleListener，监听LifecycleEvent
                ContextConfig contextConfig=null;
                contextConfig.webConfig();// step4、5处理@HandlesTypes、@WebServlet、@WebListener、@WebFilter注解
                contextConfig.processServletContainerInitializers();
                // 声明ServletContainerInitializer感兴趣的类
                // Byte Code Engineering Library (BCEL)；字节码操作框架，读取全部类判断
                HandlesTypes handlesTypes;
                WebFilter webFilter;

                // 执行ServletContainerInitializer回调。5098
                new StandardContext().startInternal();
            }

        }
        WebApplicationInitializer webApplicationInitializer;// 容器启动回调
        LifecycleProcessor lifecycleProcessor;// 上下文刷新、销毁回调

        /* step2，spring上下文refresh前回调；*/
        // servletContext globalInitializerClasses、contextInitializerClasses配置；
        ApplicationContextInitializer applicationContextInitializer;
        DubboApplicationContextInitializer dubboApplicationContextInitializer;
        ContextLoader.customizeContext();// 调用点
        LifecycleProcessor lifecycleProcessor;

        /* step3，bean生命周期相关扩展*/
        // AnnotationConfigRegistry扫描class，生成beanDefinition后回调；形参传入
        BeanDefinitionCustomizer beanDefinitionCustomizer;
        EnvironmentPostProcessor environmentPostProcessor;// env处理器，spi加载
        ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent();// 调用点

        // beanFactory扫描完成后调用；来源：固定、bean
        // 注册bean definitions
        BeanDefinitionRegistryPostProcessor registryPostProcessor;
        AbstractApplicationContext.invokeBeanFactoryPostProcessors();// 调用点，refresh中
        {
            // 处理@Configuration类
            ConfigurationClassPostProcessor configurationClassPostProcessor;
            // 处理@Configuration类 @Import导入的bd
            ConfigurationClassParser parser;
            Import importA;
            ImportBeanDefinitionRegistrar registrar;// parser中导入bd

        }
        // beanFactory扫描完成后调用，registryPostProcessor后；来源：固定、bean
        // 修改bean definitions属性、早期实例化
        BeanFactoryPostProcessor factoryPostProcessor;
        // 调用点同BeanDefinitionRegistryPostProcessor，后与其

        // bean初始化完成后调用；来源：固定、bean
        //  postProcessBeforeInitialization；属性注入后回调，即初始化的第一个回调。
        //  postProcessAfterInitialization；初始化的最后一个回调
        //  部分子接口，贯穿getBean方法
        BeanPostProcessor beanPostProcessor;
        AbstractAutowireCapableBeanFactory.initializeBean();// 调用点
        {
            // 1，实例化前后回调；如aop
            //  postProcessBeforeInstantiation；实例化前调用
            //  postProcessAfterInstantiation；postProcessBeforeInstantiation后
            //  postProcessProperties；ioc中值注入前调用，调整kv
            InstantiationAwareBeanPostProcessor instantiationAwareBeanPostProcessor;
            AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation();// 调用点，createBean中
            AbstractAutowireCapableBeanFactory.populateBean();// postProcessProperties调用点
            {
                // aop相关
                AnnotationAwareAspectJAutoProxyCreator proxyCreator;
                AdvisedSupport advisedSupport;

            }

            // 2，实例化后，扫描获取待注入属性
            MergedBeanDefinitionPostProcessor mergedBeanDefinitionPostProcessor;
            AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors();// 调用点，doCreateBean中，实例化后，ioc前
            {
                // 扫描@Autowired
                AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor;
                // 扫描@Reference，注册为bd
                ReferenceAnnotationBeanPostProcessor referenceAnnotationBeanPostProcessor;
                // 扫描@Scheduled
                ScheduledAnnotationBeanPostProcessor scheduledAnnotationBeanPostProcessor;
                // 扫描@PostConstruct、@PreDestroy
                CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor;
            }

            // 3，销毁回调
            DestructionAwareBeanPostProcessor destructionAwareBeanPostProcessor;

        }

        // bean标记注解、实现接口的执行顺序
        {
            // bean实例化、初始化、销毁回调相关
            // 注解配置先于xml配置解析，可以被xml配置覆盖。
            // 顺序：BeanPostProcessor、注解、接口
            PostConstruct postConstruct;// 实例化回调
            InitializingBean initializingBean;// 设置属性后调用
            Bean bean;// initMethod、destroyMethod
            SmartInitializingSingleton initializingSingleton;// 最后的初始化回调
            PreDestroy preDestroy;// 销毁回调
            DisposableBean disposableBean;
        }

        /* step4，生命周期*/
        // start、stop事件；状态查询
        Lifecycle springLifecycle;
        // init、start、stop、destroy事件；监听器管理
        org.apache.catalina.Lifecycle tomcatLifecycle;

        /* step5，bean构建相关*/
        FactoryBean factoryBean;// 扩展构建bean方式
        ObjectFactory objectFactory;// 三级缓存中使用
        // 调用点ApplicationContextAwareProcessor，BeanPostProcessor#postProcessBeforeInitialization
        Aware aware;// 注入工具bean
        ResourceLoaderAware resourceLoaderAware;
        MessageSourceAware messageSourceAware;
        ApplicationEventPublisherAware eventPublisherAware;
        EnvironmentAware environmentAware;
        ApplicationContextAware applicationContextAware;// 整合以上
        EmbeddedValueResolverAware valueResolverAware;
        // getBean初始化时调用
        BeanNameAware beanNameAware;
        BeanClassLoaderAware beanClassLoaderAware;
        BeanFactoryAware beanFactoryAware;

    }

    /**
     *
     */
    public static void annotation(){
        /* step1，监听器、过滤器、servlet；加载？*/
        WebListener webListener;
        WebFilter webFilter;
        WebServlet webServlet;
        new ContextConfig().webConfig();// step4处理，扫描载入
        // 装配。监听器、过滤器、servlet；容器元素，spring前加载，bean初始化时可注入属性？
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(null);
        ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
        applicationContext.getBean(Spring.class);

        /* step2，Conditional族，扫描beanDefinition时处理注解处理；*/
        Conditional conditional;
        Condition condition;
        ConditionEvaluator conditionEvaluator;// 计算condition值
        {
            // springboot复合注解，实际通过Conditional实现
            ConditionalOnBean conditionalOnBean;
            OnBeanCondition onBeanCondition;
            ConditionalOnProperty conditionalOnProperty;
            OnPropertyCondition onPropertyCondition;
        }

        Qualifier q;

    }

    /**
     *
     */
    public static void initailizer(){
        // tomcat容器初始化完成回调
        ServletContainerInitializer initializer1;

        // 实现ServletContainerInitializer；适配WebApplicationInitializer
        SpringServletContainerInitializer containerInitializer;
        WebApplicationInitializer initializer2;// spring tomcat容器初始化回调。spring context

        // spring 上下文刷新前回调。spring-web
        ApplicationContextInitializer initializer3;


    }

    /**
     * https://blog.csdn.net/java_lyvee/article/details/102633067
     * bean扫描过程
     *  扫描指定路径，初始化beanDefinition。Resource方式读取，未加载class
     *  设置beanName、lazyInit、dependOn等信息
     *  保存到beanDefinitionMap
     *
     * 生成bean实例
     *  扫描构建beanDefinition
     *  反射创建实例，即实例化
     *  依赖注入
     *  初始化、初始化回调
     */
    public static void beanDefinition(){
        DefaultListableBeanFactory bf2=null;
        bf2.registerBeanDefinition("", null);
        /* step1，描述bean；包含属性、lazyInit、primary、initMethod等信息*/
        BeanDefinition beanDefinition;
        {
            AnnotatedGenericBeanDefinition annotatedBeanDefinition;
            GenericBeanDefinition genericBeanDefinition;
            // root、child类似装饰器模式；
            // root无parent，child必须有parent；
            // child无setter时，使用root值
            RootBeanDefinition rootBeanDefinition;
            ChildBeanDefinition childBeanDefinition;
        }

        /* step2，BeanDefinition加载*/
        AnnotatedBeanDefinitionReader classReader;// 扫描代码注册的class
        ClassPathBeanDefinitionScanner dirReader;// 路径扫描注解bean，通过Resource加载类信息
        BeanDefinitionParser beanDefinitionParser;// xml bean扫描


    }

    /**
     * getBean过程
     *  按name获取beanDefinition
     *  反射创建实例
     *  注入属性
     *
     *
     * BeanFactory属性
     *  bean缓存
     *  Map<String, BeanDefinition> beanDefinitionMap；扫描创建的bean定义集合
     *  Map<String, ObjectFactory<?>> singletonFactories；单例工厂缓存：Bean 名称到 ObjectFactory。此时bean已实例化，但通过ObjectFactory的形式被缓存
     *  Map<String, Object> earlySingletonObjects；早期单例对象的缓存：bean 名称到 bean 实例
     *  ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache；未完成的 FactoryBean 实例的缓存：FactoryBean 名称到 BeanWrapper
     *  Map<String,Object> singletonObjects；单例对象缓存：bean 名称到 bean 实例
     *  ThreadLocal<Object> prototypesCurrentlyInCreation；当前正在创建的prototype bean 的名称
     *
     *  Spring三级缓存 https://blog.csdn.net/f641385712/article/details/92801300
     *  三级缓存，getSingleton方法
     *      singletonObjects、earlySingletonObjects、singletonFactories。
     *      只有一个集合中有对应beanName
     *      earlySingletonObjects、singletonFactories(返回bean、代理bean)；只用于三级缓存，处理循环依赖
     *      三级缓存，与生命周期无关；singletonFactories允许循环依赖时添加，earlySingletonObjects允许提前曝光时添加。双开关？
     *
     *  beanName缓存
     *  Set<String> singletonsCurrentlyInCreation；正在创建的单例bean beanName
     *  Set<String> alreadyCreated；已至少创建一次的 bean 的名称
     *  Map<String, Set<String>> dependentBeanMap；依赖bean名称之间的映射：bean名称到依赖bean名称集
     *  Map<String, Set<String>> dependenciesForBeanMap；反向，依赖 bean 名称之间的映射：bean 名称到 bean 依赖项的 bean 名称集。
     *  NamedThreadLocal<String> currentlyCreatedBean；当前创建的 bean 的名称，用于对从用户指定的供应商回调触发的 getBean 等调用进行隐式依赖注册
     *  Set<String> registeredSingletons；一组已注册的单例，包含按注册顺序排列的 bean 名称
     *
     */
    public static void getBean() {
        AbstractBeanFactory beanFactory = null;
        beanFactory.getBean("");
        beanFactory.doGetBean("", null, null, null);
        {
            // beanName处理；移除全部factoryBean前缀&，别名转为beanName
            beanFactory.transformedBeanName("");
            // 获取单例bean；单例缓存singletonObjects、早期缓存earlySingletonObjects、单例工厂缓存singletonFactories
            beanFactory.getSingleton("");
            // 1，若获取到bean；factoryBean转bean
            beanFactory.getObjectForBeanInstance("", null, null, null);
            // 2，若未获取到bean；
            {
                // 父容器创建、获取

                // 处理依赖，直接依赖、传递依赖；创建对应bean
                {
                    // 判断依赖关系，depends-on属性、@DependsOn；循环依赖时抛异常
                    beanFactory.isDependent("", "");
                    DependsOn dependsOn;
                    // 注册依赖关系；dependentBeanMap、dependenciesForBeanMap
                    beanFactory.registerDependentBean("", "");
                    // getBean触发创建依赖bean
                }

                // 构建bean，注入属性
                ((AbstractAutowireCapableBeanFactory)beanFactory).createBean("", null, null);
                {
                    // 解析bean类型
                    // 处理bean查询方法，解析@Lookup等
                    Lookup lookup;
                    LookupOverride lookupOverride;
                    // 实例化bean；返回代理对象、或原对象
                    // case1，InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation、postProcessAfterInitialization
                    ((AbstractAutowireCapableBeanFactory)beanFactory).resolveBeforeInstantiation("", null);
                    {

                    }
                    // case2，构建对象，BeanWrapper注入属性
                    ((AbstractAutowireCapableBeanFactory)beanFactory).doCreateBean("", null, null);
                    {
                        // 获取FactoryBean，或直接构建bean(Supplier对象、工厂方法、构造器反射)
                        // 构造器，按入参列表选择；默认为无参构造器
                        ((AbstractAutowireCapableBeanFactory)beanFactory).createBeanInstance("", null, null);
                        Supplier supplier;
                        ((AbstractAutowireCapableBeanFactory)beanFactory).instantiateBean("", null);
                        // 调用MergedBeanDefinitionPostProcessor，修改beanDefinition的注入属性，扫描增加
                        ((AbstractAutowireCapableBeanFactory)beanFactory).applyMergedBeanDefinitionPostProcessors(null, null, "");
                        MergedBeanDefinitionPostProcessor mergedBeanDefinitionPostProcessor;
                        // 添加ObjectFactory，处理循环依赖；移除earlySingletonObjects对应beanName
                        // 单例、允许循环依赖、正在创建；
                        beanFactory.addSingletonFactory("", null);
                        {
                            ((AbstractAutowireCapableBeanFactory)beanFactory).getEarlyBeanReference(null, null, null);
                            // 获取bean前处理，如代理
                            SmartInstantiationAwareBeanPostProcessor smartInstantiationAwareBeanPostProcessor;
                        }
                        // 装配bean
                        ((AbstractAutowireCapableBeanFactory)beanFactory).populateBean("", null, null);
                        {
                            // 调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation；有处理则直接返回

                            // 按beanName、beanType装配MutablePropertyValues，设置k-v对。
                            // 判定是否包含；获取bean；设置k-v对；注册依赖关系
                            ((AbstractAutowireCapableBeanFactory)beanFactory).autowireByName("", null, null, null);
                            ((AbstractAutowireCapableBeanFactory)beanFactory).autowireByType("", null, null,  null);
                            MutablePropertyValues propertyValues;
                            // 调用InstantiationAwareBeanPostProcessor#postProcessPropertyValues

                            // 依赖检查；检查是否全部需设置的属性已在propertyValues
                            ((AbstractAutowireCapableBeanFactory)beanFactory).checkDependencies("", null, null,  null);
                            // 实际值注入，集合使用深拷贝，集合元素未深拷贝
                            // 获取k-v对集合；构建拷贝deepCopy，k-解析后bean；替换MutablePropertyValues；遍历反射赋值
                            ((AbstractAutowireCapableBeanFactory)beanFactory).applyPropertyValues("", null, null);

                        }
                        // 初始化bean；执行回调
                        ((AbstractAutowireCapableBeanFactory)beanFactory).initializeBean("", null, null);
                        {
                            // Aware接口调用；调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
                            ((AbstractAutowireCapableBeanFactory)beanFactory).invokeAwareMethods("", null);
                            // BeanPostProcessor#postProcessBeforeInitialization
                            // 执行初始化回调
                            // InitializingBean#afterPropertiesSet；initMethod
                            ((AbstractAutowireCapableBeanFactory)beanFactory).invokeInitMethods("", null, null);
                            // BeanPostProcessor#postProcessAfterInitialization

                        }

                    }

                }

            }

            // 类型转换；ConversionService
            new GenericConversionService().convert(null, (Class)null);

        }
    }

    /**
     * 过程：
     *  1，加载bd
     *  2，初始获取时注册到bean容器。
     *
     *
     */
    public static void ioc(){
        /* step1，结构。*/
        // 实现类加载、持有bd集合；初始获取时注册到bean容器
        BeanFactory bf;
        BeanDefinition bd;
        // bean


    }

    /**
     * aop源码分析
     *  https://www.cnblogs.com/toby-xu/p/11444288.html
     *  核心处理：
     *      InstantiationBeanPostProcessor.postProcessBeforeInstantiation
     *      SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
     *
     */
    public static void aop(){
        /* step1，开启aop*/
        // Import导入AspectJAutoProxyRegistrar bean
        EnableAspectJAutoProxy enableAspectJAutoProxy;
        // 注册AnnotationAwareAspectJAutoProxyCreator
        AspectJAutoProxyRegistrar aspectJAutoProxyRegistrar;

        /* step2，生成代理类*/
        // 实现InstantiationAwareBeanPostProcessor，beanDefinition实例化时返回代理类
        AnnotationAwareAspectJAutoProxyCreator aopProxyCreator=null;
        aopProxyCreator.postProcessBeforeInstantiation(null, null);
        SmartInstantiationAwareBeanPostProcessor postProcessor;

        /* step3，切面切点注解*/
        Aspect aspect;
        Pointcut pointcut;
        Before before;
        After after;
        AfterReturning afterReturning;
        AfterThrowing afterThrowing;
        Around around;


    }

    /**
     * Import处理
     *  https://www.cnblogs.com/grasp/p/11906642.html
     *
     */
    public static void importAnno(){
        /* step1，导入bean定义；与@Configuration联用*/
        Import importAnno;
        Configuration configuration;
        {
            // 特殊beanDefinition；注册后回调方法，引入新的beanDefinition
            ImportSelector importSelector;
            DeferredImportSelector deferredImportSelector;
            ImportBeanDefinitionRegistrar registrar;
        }
        ImportResource importResource;

        /* step2，处理Import*/
        // load bd时载入，默认、手动
        // BeanDefinitionRegistryPostProcessor；beanDefinition注册后回调
        ConfigurationClassPostProcessor configurationClassPostProcessor=null;
        configurationClassPostProcessor.processConfigBeanDefinitions(null);
        // 处理@PropertySources，@ComponentScan，@Import，@ImportResource，@Bean方法，
        // 注册BeanDefinition
        ConfigurationClassParser parser=null;
        parser.processImports(null, null, null, null);


    }

    /**
     *
     */
    public static void loadBeanDefinition(){
        AbstractApplicationContext context=null;
        context.obtainFreshBeanFactory();
        ((AbstractRefreshableApplicationContext)context).refreshBeanFactory();
        ((AbstractXmlApplicationContext)context).loadBeanDefinitions((DefaultListableBeanFactory)null);
        ((AbstractXmlApplicationContext)context).loadBeanDefinitions((XmlBeanDefinitionReader)null);
        {
            XmlBeanDefinitionReader reader=null;
            // 1，
            // 加载资源文件
            reader.loadBeanDefinitions((String)null);
            // 最终还是通过Resource加载bd
            reader.loadBeanDefinitions((Resource)null);

            // 2，
            reader.doLoadBeanDefinitions(null, null);
            {
                reader.doLoadDocument(null, null);
                DefaultDocumentLoader.loadDocument(null, null, null, 1, false);
                DocumentBuilderImpl.parse((InputSource)null);
                DOMParser.parse((InputSource)null);
                DOMParser.parse((XMLInputSource)null);
                XML11Configuration.parse((XMLInputSource)null);
                XMLVersionDetector.startDocumentParsing(null, 1);// 预配置？
                XMLDocumentFragmentScannerImpl.scanDocument(true);

            }
        }

    }

    /**
     * 配置文件
     *  注解导入、配置PropertySourcesPlaceholderConfigurer bean
     *  bootstrap.yml；spring cloud启动配置
     *
     */
    public static void configFile(){
        PropertySource propertySource;// 配置导入到environment
        PropertySources propertySources;
        // bf扫描完成后，ConfigurationClassParser中调用解析，加入env
        ConfigurationClassParser parser;
        DefaultPropertySourceFactory propertySourceFactory;

        // 占位符解析器，配置不放入environment
        // 实现BeanFactoryPostProcessor(加载配置文件)、EnvironmentAware(解析环境属性)
        PropertySourcesPlaceholderConfigurer configurer;
        BeanFactoryPostProcessor b;
        /* step1，environment加载配置文件*/
        // spring中，environment不加载application配置文件；
        StandardEnvironment standardEnvironment;// 加载os、jvm属性
        AbstractEnvironment abstractEnvironment;// 继承本类，调用customizePropertySources初始化

        // springboot
        // 配置占位符解析器
        PropertyPlaceholderAutoConfiguration propertyPlaceholderAutoConfiguration;
        // 继承StandardEnvironment，初始化servlet、jndi
        StandardServletEnvironment springbootEnvironment;
        // env准备好后，导入application配置文件到env；spi加载
        ConfigFileApplicationListener configFileApplicationListener;
        EnvironmentPostProcessor environmentPostProcessor;// env处理器

        // 注入配置属性；
        ConfigurationProperties configurationProperties;
        // BeanPostProcessor
        ConfigurationPropertiesBindingPostProcessor processor;
    }

    /**
     *
     */
    public static void integrate(){
        Mybatis.spring();

    }

    /**
     * https://blog.csdn.net/u010086122/article/details/81607127
     */
    public static void resource() throws IOException {
        Resource resource=null;// 可访问jar包内资源
        URL url;// 资源访问地址
        URI uri;// 资源唯一标识
        File file;// 操作系统中的文件
        ApplicationContext context=null;
        context.getResource("");
        ResourceLoader resourceLoader;
        ResourceUtils resourceUtils;

        resource.getInputStream().read(null);// 读取resource内容，避免通过File读取

        Resources.getResourceAsFile("");// mybatis工具类，通过ClassLoader加载文件

    }

    /**
     *
     */
    public static void validator(){
        CheckAnnotation.check();// java校验

        Validator validator;// spring校验接口。实现、显示调用
        Errors errors;// 存储校验对象属性、校验结果
        ValidationUtils validationUtils;




    }

    /**
     *
     */
    public static void transaction() throws NamingException {
        // 实现JTA事务管理接口 UserTransaction
        UserTransactionAdapter userTransactionAdapter;
        TransactionManager tm;
        DataSourceTransactionManager tm1;// 本地事务
        JtaTransactionManager tm2;// jta事务，分布式事务

        XADataSource xaDataSource;
        XAConnection xaConnection;
        XAResource xaResource;


        // JNDI；类似spi的接口实现类查找
        InitialContext context=new InitialContext();

        // 声明式事务。aop方式实现，通过tm进行事务管理
        // https://blog.csdn.net/qq_20597727/article/details/84868035
        Transactional transactional;
        {
            Isolation isolation;
            Propagation propagation;
        }
        BeanFactoryTransactionAttributeSourceAdvisor aop;
        TransactionInterceptor transactionInterceptor;

        ConnectionHolder connectionHolder;// 包装conn，绑定到当前线程

        // 编程式事务。通过jdbc执行sql
        TransactionTemplate transactionTemplate;
        PlatformTransactionManager transactionManager;

    }

    static class Start{
        public static void start(){
            // 容器生命周期：init；start；stop；destroy
            // 扩展方式：回调接口、发布事件
            org.apache.catalina.Lifecycle lifecycle;
            StandardContext serverContext=null;// 容器上下文
            serverContext.start();
            serverContext.startInternal();// 应用启动
            {
                // 回调ServletContainerInitializer接口，实例化rootContext、dispatcherServlet。5095行

                // 发布context初始化事件，刷新rootContext。5095行
                serverContext.listenerStart();
                // 初始化load-on-startup servlet，调用init方法。5143行
                serverContext.loadOnStartup(null);

            }

            /* step1，创建rootContext、dispatcherServlet*/
            // 编程式配置web.xml；https://blog.csdn.net/z69183787/article/details/104557820*/
            // 容器初始化后回调，spi加载
            ServletContainerInitializer servletContainerInitializer;
            {
                // 实际会适配到WebApplicationInitializer
                SpringServletContainerInitializer springServletContainerInitializer;
                // spi
                WebApplicationInitializer webApplicationInitializer;
                AbstractDispatcherServletInitializer initializer=null;// 抽象类
                initializer.onStartup(null);
                {
                    initializer.onStartup(null);// 实例化rootContext
                    initializer.registerDispatcherServlet(null);// 实例化dispatcherServlet
                }
            }

            /* step2，刷新rootContext*/
            ContextLoaderListener loaderListener=null;
            loaderListener.contextInitialized(null);
            loaderListener.initWebApplicationContext(null);

            /* step3，Servlet#init*/
            Servlet servlet;
            DispatcherServlet dispatcher=null;
            dispatcher.init(null);
            dispatcher.init();
            {
                // 从servletConfig解析init-param

                // servlet刷新
                dispatcher.onRefresh(null);
            }


        }
    };

    static class IoC{

    };

    /**
     * 加载servlet，加载mvc
     *  加载servlet时机。web.xml
     *  加载mvc方式
     *
     */
    static class Mvc{

        public static void servlet(){
            // 接口定义结构；模板方法扩展
            Servlet servlet;// java定义
            GenericServlet genericServlet;// 通用servlet模板，协议无关。抽象类
            HttpServlet httpServlet;// http servlet；抽象，继承以处理请求
            HttpServletBean httpServletBean;// init-param通过bean属性解析，从servletConfig获取
            FrameworkServlet frameworkServlet;// spring基础servlet；提供servletContext管理，req请求事件发布
            DispatcherServlet dispatcherServlet;

        }

        public static void context(){
            /*
             * 上下文层级
             *  1，serverContext持有rootContext、servletContext
             *  2，rootContext持有serverContext。无配置时为null
             *  3，servletContext持有rootContext。无servlet config配置时为空对象
             *  4，bean查找时，从下往上，可覆盖。
             */
            ServletContext serverContext;
            WebApplicationContext rootContext;// 公用
            WebApplicationContext servletContext;// servlet自定义上下文

            // 获取servletContext
            WebApplicationContext webApplicationContext = RequestContextUtils.findWebApplicationContext((HttpServletRequest) null);

        }

        public static void servletRefresh(){
            WebApplicationContext servletContext=null;
            DispatcherServlet dispatcher=new DispatcherServlet(servletContext);
            dispatcher.onRefresh(servletContext);// 初始化回调。入口为Servlet#init
            // context.getBean获取对象；无时为DispatcherServlet.properties配置，类spi
            dispatcher.initStrategies(servletContext);
            {
                // 1，初始化分段文件解析器
                MultipartResolver multipartResolver;
                dispatcher.initMultipartResolver(servletContext);
                // 2，初始化本地化解析器
                LocaleResolver localeResolver;
                dispatcher.initLocaleResolver(servletContext);
                // 3，初始化主题解析器
                ThemeResolver themeResolver;
                dispatcher.initThemeResolver(servletContext);
                // 4，初始化HandlerMapping
                HandlerMapping handlerMapping;
                dispatcher.initHandlerMappings(servletContext);
                // 5，初始化HandlerAdapter
                HandlerAdapter handlerAdapter;
                dispatcher.initHandlerAdapters(servletContext);dispatcher.getServletContext()
                // 6，初始化异常处理器
                HandlerExceptionResolver handlerExceptionResolver;
                dispatcher.initHandlerExceptionResolvers(servletContext);
                // 7，初始化RequestToViewNameTranslator，请求转视图
                // 四类：handling、redirecting、forwarding、content negotiation
                RequestToViewNameTranslator requestToViewNameTranslator;
                dispatcher.initRequestToViewNameTranslator(servletContext);
                // 8，初始化视图解析器
                ViewResolver viewResolver;
                dispatcher.initViewResolvers(servletContext);
                // 9，初始化FlashMap管理器，用于重定向时暂存请求数据
                FlashMapManager flashMapManager;
                dispatcher.initFlashMapManager(servletContext);
            }
        }

        public static void config(){
            /* step1，mvc配置；servlet 9组件*/
            EnableWebMvc enableWebMvc;// 启用web mvc，导入相关自动配置
            WebMvcConfigurer webMvcConfigurer;// 自定义配置接口
            WebMvcConfigurerAdapter webMvcConfigurerAdapter;// 空实现的模板类
            WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter springBootImpl;// 参考实现

            /* step2，servlet config*/
            WebApplicationInitializer webApplicationInitializer;
            AbstractDispatcherServletInitializer initializer1;
            AbstractAnnotationConfigDispatcherServletInitializer initializer2;

        }

        public static void execute() throws Exception {
            DispatcherServlet dispatcher=null;
            dispatcher.service((ServletRequest) null, (ServletResponse) null);// tomcat servlet接收请求
            ((FrameworkServlet)dispatcher).service((HttpServletRequest)null, (HttpServletResponse)null);// spring servlet接收请求
            dispatcher.processRequest((HttpServletRequest)null, (HttpServletResponse)null);
            dispatcher.doService(null, null);
            {
                // 记录请求日志。打印请求头、参数，配置enableLoggingRequestDetails
                dispatcher.logRequest(null);
                // req绑定servletContext等
                dispatcher.doDispatch(null, null);
                {
                    // 检查、转换为MultipartHttpServletRequest
                    dispatcher.checkMultipart(null);
                    // 多个HandlerMapping中选择handler
                    HandlerExecutionChain handlerChain = dispatcher.getHandler(null);
                    getHandler();
                    // 获取handler匹配的HandlerAdapter，执行请求
                    HandlerAdapter ha = dispatcher.getHandlerAdapter(null);
                    ModelAndView mv = ha.handle(null, null, null);
                    // 执行拦截器postHandle
                    handlerChain.applyPostHandle(null, null, null);
                    // 返回结果，执行afterCompletion
                    dispatcher.processDispatchResult(null, null, null);
                }

            }


        }

        /**
         *
         */
        public static void getHandler(){
            DispatcherServlet dispatcher=null;
            HandlerExecutionChain handler = dispatcher.getHandler(null);
            {
                HandlerMapping handlerMapping=null;
                handler = handlerMapping.getHandler(null);
                {
                    // 路径匹配，获取handlerMethod
                    HandlerMethod handlerMethod;
                    Object handlerInternal = ((AbstractHandlerMapping) handlerMapping).getHandlerInternal(null);
                    // 封装为chain；附加common、匹配的拦截器
                    HandlerExecutionChain executionChain = ((AbstractHandlerMapping) handlerMapping).getHandlerExecutionChain(handler, null);
                    // cors，跨域处理
                    ((AbstractHandlerMapping) handlerMapping).getCorsHandlerExecutionChain(null, null, null);
                }

            }

            // handler相关
            HandlerMapping hm;
            HandlerMethod handler1;
            HandlerInterceptor hi;// 拦截器
            HandlerExecutionChain chain;
            HandlerAdapter ha;// handler适配器
            {
                SimpleControllerHandlerAdapter ha1;
                SimpleServletHandlerAdapter ha2;
            }
        }

    };
}
